package com.fengye.middleware.redis.demo;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fengye.middleware.redis.model.Fruit;
import com.fengye.middleware.redis.model.User;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.*;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * Redis常见数据结构
 * @author sky
 * @date 2021/06/07 22:04
 */
@Component
@Slf4j
public class RedisDataConstruct {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Autowired
    private ObjectMapper objectMapper;
    /**
     * Redis存、取字符串
     */
    public void string() {

        ValueOperations<String, Object> operations = redisTemplate.opsForValue();
        String KEY = "REDIS:DATA:STRUCT:KEY";
        String VALUE = "REDIS:DATA:STRUCT:VALUE";
        operations.set(KEY, VALUE);
        log.info("写入redis: key={},value={}", KEY, VALUE);
        Object obj = operations.get(KEY);
        log.info("读取redis：key={},value={}", KEY, obj);
    }

    public void list() {
        String key = "REDIS:DATA:STRUCT:LIST:KEY";
        List<User> users = new ArrayList<>();
        users.add(new User(1, "info", "宙斯"));
        users.add(new User(2, "error", "哈迪斯"));
        users.add(new User(2, "debug", "波塞冬"));
        users.add(new User(5, "warn", "雅典娜"));
        users.add(new User(5, "trace", "星矢"));
        ListOperations<String, Object> operations = redisTemplate.opsForList();
        users.forEach(u -> {
            operations.leftPush(key, u);
        });

        log.info("将list={},写入Redis中", users);

        Object obj = operations.rightPop(key);
        while (obj != null){
            log.info("读取Redis中的list,key={},value={}",key, obj);
            obj = operations.rightPop(key);
        }
    }

    public void set() {
        String key = "REDIS:DATA:STRUCT:SET:KEY";
        List<User> users = new ArrayList<>();
        users.add(new User(1, "info", "宙斯"));
        users.add(new User(2, "error", "哈迪斯"));
        users.add(new User(2, "debug", "波塞冬"));
        users.add(new User(4, "warn", "雅典娜"));
        users.add(new User(4, "trace", "星矢"));
        SetOperations<String, Object> operations = redisTemplate.opsForSet();
        users.forEach(u -> {
            operations.add(key, u);
        });

        log.info("将list={},写入Redis中", users);

        Object obj = operations.pop(key);
        while (obj != null){
            log.info("读取Redis中的set,key={},value={}",key, obj);
            obj = operations.pop(key);
        }
    }

    public void zSet(){
        String key = "REDIS:DATA:STRUCT:ZSET:KEY";
        List<User> users = new ArrayList<>();
        users.add(new User(1, "info", "宙斯"));
        users.add(new User(2, "error", "哈迪斯"));
        users.add(new User(2, "debug", "波塞冬"));
        users.add(new User(4, "warn", "雅典娜"));
        users.add(new User(4, "trace", "星矢"));

        // 清空数据
        redisTemplate.delete(key);

        // 获取有序集合 SortedSet 操作组件 ZSetOperations
        ZSetOperations<String, Object> zSetOperations = redisTemplate.opsForZSet();
        users.forEach(user -> zSetOperations.add(key, user, user.getId()));
        Long size = zSetOperations.size(key);

        // 从小到大排序
        Set<Object> resSet = zSetOperations.range(key, 0L, size);


        // 从大到小排序
        Set<Object> resReverse = zSetOperations.reverseRange(key, 0L, size);
        assert resSet != null;
        resSet.forEach(s->log.info("获取 key为{},value={}",key, s));

    }

    public void hash() {
        String keyUser = "REDIS:DATA:STRUCT:HASH:USER:KEY";
        String keyFruit = "REDIS:DATA:STRUCT:HASH:FRUIT:KEY";
        List<User> users = new ArrayList<>();
        List<Fruit> fruits = new ArrayList<>();
        users.add(new User(1, "info", "宙斯"));
        users.add(new User(2, "error", "哈迪斯"));
        users.add(new User(2, "debug", "波塞冬"));
        users.add(new User(4, "warn", "雅典娜"));
        users.add(new User(4, "trace", "星矢"));

        fruits.add(new Fruit("橘子","orange"));
        fruits.add(new Fruit("苹果","red"));
        fruits.add(new Fruit("黄瓜","green"));

        HashOperations<String, Object, Object> hashOperations = redisTemplate.opsForHash();
        users.forEach(u -> hashOperations.put(keyUser, u.getId(), u));
        fruits.forEach(f-> hashOperations.put(keyFruit, f.getName(), f));

        Map<Object, Object> userMap = hashOperations.entries(keyUser);
        log.info("获取数据users：{}", userMap);
        Map<Object, Object> fruitMap = hashOperations.entries(keyFruit);
        log.info("获取数据fruits：{}", fruitMap);

        // 获取指定的用户
        String uField = "1";
        User user = (User) hashOperations.get(keyUser, uField);
        log.info("获取指定的用户，id={},user={}", uField, user);

        String fField = "苹果";
        Fruit fruit = (Fruit) hashOperations.get(keyFruit, fField);
        log.info("获取指定的水果：name={},fruit={}", fField, fruit);
    }
}
